#include <windows.h>
#include "lnstring.h"

unsigned  ln_string_hash (unsigned n, const char* s)
{
  unsigned a,b;
  while (*s)
  {
    a = n >> 3;
    b = n << 5;
    n = a + b + (unsigned)*s;
  };

  return n;
};

string_map_p 
string_map_at (
    string_map_p map,
    string_map_p * cache,
    int cache_size,
    int id)
{
  string_map_p cache_tmp;

  if (cache)
  {
    cache += ((unsigned)(id)) % ((unsigned)cache_size);
  }
  else
  {
    cache = &cache_tmp;
    cache_tmp = NULL;
  };

  if ( *cache == NULL || (*cache)->id != id)
  {
    *cache = NULL;

    for (;map->string; map++)
    {
      if (map->id == id)
      {
        *cache = map;
        break;
      }
    }
  };

  return *cache;
};

int
string_map_find (
    string_map_p map,
    string_map_p * cache,
    int cache_size,
    const char* s)
{
  unsigned id;
  
  if (cache)
  {
    id = ln_string_hash (0, s);
    cache += id % (unsigned)cache_size;

    if (*cache && strcmp ( (*cache)->string, s) == 0 )
    {
      return (*cache)->id;
    }
  }

  for (;map->string; map++)
  {
    if ( strcmp(map->string, s) == 0 )
    {
      if (cache)
      {
        *cache = map;
      }

      return map->id;
    };
  }

  return 0;
}

void string_list_delete (char** list,int count)
{
  char** src;

  for ( src = list + count; *src;)
  {
    *(list++) = *(src++);
  }
}

int
string_list_count (char** list)
{
  int n = 0;
  if (list)
  {
    while (*list)
    {
      n++;
      list++;
    }
  }

  return n;
};
